package com.design.reactor.stretchIO._4_masterSlaveReactorMultiThread.handler;

import com.design.reactor.stretchIO._4_masterSlaveReactorMultiThread.SubReactor;

import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

// 接受連線請求線程
public class AcceptorHandler implements Handler {
    private final ServerSocketChannel ssc; // mainReactor監聽的socket通道
    private final SubReactor[] subReactors = new SubReactor[Runtime.getRuntime().availableProcessors()]; // subReactor線程
    private int selIdx = 0; // 當前可使用的subReactor索引

    public AcceptorHandler(ServerSocketChannel ssc) throws IOException {
        this.ssc = ssc;
        // 創建多個selector以及多個subReactor線程
        for (int i = 0; i < subReactors.length; i++) {
            subReactors[i] = new SubReactor();
//            new Thread(subReactors[i]).start();
        }
//        try {
//            Thread.sleep(1000);
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }
    }

    @Override
    public void processes() {
        try {
            SocketChannel sc = ssc.accept(); // 接受client連線請求
            sc.configureBlocking(false); // 設置為非阻塞
            SubReactor subReactor = subReactors[selIdx];
            Selector selector = subReactor.getSelector();
            selector.wakeup();
            SelectionKey sk = sc.register(selector, 0);//注册一个不存在的事件
            sk.attach(new DataHandler(sk, sc)); // 給定key一個附加的TCPHandler對象
            sk.interestOps(SelectionKey.OP_READ); //注册读事件
            selector.wakeup();
            if (++selIdx == subReactors.length) selIdx = 0;
            if (!subReactor.isThreadStarted()) {
                subReactor.setThreadStarted(true);
                new Thread(subReactor).start();
            }
            System.out.println("线程 ：" + Thread.currentThread().getName() + ",当前类 ；" + getClass().getName() + " 的 hashCode :" + this.hashCode() + ",此 selector< " + selector.hashCode() + " > 多路复用器上注册的事件是 ：可读事件");
        } catch (IOException e) {
            e.getLocalizedMessage();
        }
    }
}
